/*
 * Copyright (c) 2015-2018 Sfkj Science And Technology Co.,Ltd.
 * All Rights Reserved.
 * This software is the confidential and proprietary information of
 * Sfkj Science And Technology Co.,Ltd.
 * ("Confidential Information").You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Sfkj.
 */
package com.sfkj.walk.query.activity;

import com.alibaba.fastjson.JSON;
import com.sfkj.walk.api.activity.*;
import com.sfkj.walk.api.note.NoteCreatedEvent;
import com.sfkj.walk.api.note.NoteDeletedEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.eventhandling.MetaDataConstants;
import org.axonframework.eventhandling.Timestamp;
import org.axonframework.messaging.annotation.MetaDataValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Objects;

@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Component
class ActivityListener {

    private final ActivityRepository repository;
    private final ActivityMemberRepository activityMemberRepository;

    @EventHandler
    public void on(final ActivityCreatedEvent event, @Timestamp Instant timestamp,
                   @MetaDataValue(MetaDataConstants.CURRENT_USER_ID) String currentUserId) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = new Activity();
        queryObject.setId(event.getId());
        queryObject.setActivityType(event.getActivityType());
        queryObject.setTitle(event.getTitle());
        queryObject.setIntroduction(event.getIntroduction());
        queryObject.setCoverUrl(event.getCoverUrl());
        queryObject.setTime(event.getTime());

        if (Objects.nonNull(event.getTime())) {
            queryObject.setYear(event.getTime().getStart().getYear());
            queryObject.setMonth(event.getTime().getStart().getMonth().getValue());
        }
        queryObject.setCreatorId(currentUserId);
        queryObject.setMemberCount(0L);
        queryObject.setNoteCount(0L);
        queryObject.setViewCount(0L);
        queryObject.setCollectCount(0L);

        queryObject.setCreatedDate(LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault()));
        queryObject.setLastUpdate(LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault()));

        repository.save(queryObject);
    }

    @EventHandler
    public void on(final ActivityChangedEvent event, @Timestamp Instant timestamp) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = repository.findOne(event.getId());
        queryObject.setActivityType(event.getActivityType());
        queryObject.setTitle(event.getTitle());
        queryObject.setIntroduction(event.getIntroduction());
        queryObject.setCoverUrl(event.getCoverUrl());
        queryObject.setTime(event.getTime());

        queryObject.setLastUpdate(LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault()));

        repository.save(queryObject);
    }

    @EventHandler
    public void on(final ActivityDeletedEvent event) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        repository.delete(event.getId());
    }

    @EventHandler
    public void on(final MemberJoinedEvent event) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = repository.findOne(event.getId());
        queryObject.setMemberCount(activityMemberRepository.countByActivityId(event.getId()));

        repository.save(queryObject);
    }

    @EventHandler
    public void on(final MemberRemovedEvent event) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = repository.findOne(event.getId());
        queryObject.setMemberCount(activityMemberRepository.countByActivityId(event.getId()));

        repository.save(queryObject);
    }

    @EventHandler
    public void on(final NoteCreatedEvent event) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = repository.findOne(event.getActivityId());
        queryObject.setNoteCount(queryObject.getNoteCount() + 1);

        repository.save(queryObject);
    }

    @EventHandler
    public void on(final NoteDeletedEvent event) {
        log.info("Caught: {}, identifier:{}", event.getClass().getSimpleName(), JSON.toJSONString(event));

        Activity queryObject = repository.findOne(event.getActivityId());
        queryObject.setNoteCount(queryObject.getNoteCount() - 1);

        repository.save(queryObject);
    }

}
